home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / RCSC.ZIP / LIB51 / SSCANF.C < prev    next >
C/C++ Source or Header  |  1997-01-12  |  2KB  |  67 lines

  1. /*
  2. ** sscanf(buffer, ctlstring, arg, arg, ...) - Formatted read.
  3. ** Operates as described by Kernighan & Ritchie.
  4. ** b, c, d, o, s, u, and x specifications are supported.
  5. ** Note: b (binary) is a non-standard extension.
  6. */
  7. sscanf(argc) int argc; {
  8.   int *nxtarg;
  9.   char *carg, *ctl, *ptr;
  10.   unsigned u;
  11.   int  *narg, wast, ac, width, ch, cnv, base, ovfl, sign;
  12.   ac = 0;
  13.   nxtarg = &argc - CCARGC() + 1;
  14.   ptr = *nxtarg++;
  15.   ctl = *nxtarg++;
  16.   while(*ctl) {
  17.     if(isspace(*ctl)) {++ctl; continue;}
  18.     if(*ctl++ != '%') continue;
  19.     if(*ctl == '*') {narg = carg = &wast; ++ctl;}
  20.     else             narg = carg = *nxtarg++;
  21.     ctl += utoi(ctl, &width);
  22.     if(!width) width = 32767;
  23.     if(!(cnv = *ctl++)) break;
  24.     while(isspace(ch = *ptr++)) ;
  25.     if(ch == 0) {if(ac) break; else return(EOF);}
  26.     --ptr;;
  27.     switch(cnv) {
  28.       case 'c':
  29.         *carg = *ptr++;
  30.         break;
  31.       case 's':
  32.         while(width--) {
  33.           if((*carg = *ptr++) == 0) break;
  34.           if(isspace(*carg)) break;
  35.           if(carg != &wast) ++carg;
  36.           }
  37.         *carg = 0;
  38.         break;
  39.       default:
  40.         switch(cnv) {
  41.           case 'b': base =  2; sign = 1; ovfl = 32767; break;
  42.           case 'd': base = 10; sign = 0; ovfl =  3276; break;
  43.           case 'o': base =  8; sign = 1; ovfl =  8191; break;
  44.           case 'u': base = 10; sign = 1; ovfl =  6553; break;
  45.           case 'x': base = 16; sign = 1; ovfl =  4095; break;
  46.           default:  return (ac);
  47.           }
  48.         *narg = u = 0;
  49.         while(width-- && !isspace(ch=*ptr++) && ch!=0) {
  50.           if(!sign)
  51.             if(ch == '-') {sign = -1; continue;}
  52.             else sign = 1;
  53.           if(ch < '0') return (ac);
  54.           if(ch >= 'a')      ch -= 87;
  55.           else if(ch >= 'A') ch -= 55;
  56.           else               ch -= '0';
  57.           if(ch >= base || u > ovfl) return (ac);
  58.           u = u * base + ch;
  59.           }
  60.         *narg = sign * u;
  61.       }
  62.     ++ac;                          
  63.     }
  64.   return (ac);
  65.   }
  66.  
  67.